// 实现这个项目的构建任务
const {src, dest, parallel, series, watch} = require('gulp');
const loadPlugins = require('gulp-load-plugins');
const del = require('del');
const plugins = loadPlugins();
const browserSync = require('browser-sync');

const bs = browserSync.create();
const cwd = process.cwd();
let config = {
	// default config
	build: {
		src: 'src',
		dist: 'dist',
		temp: 'temp',
		public: 'public',
		paths: {
			styles: 'assets/styles/*.scss',
			scripts: 'assets/scripts/*.js',
			pages: '*.html',
			images: 'assets/images/**',
			fonts: 'assets/fonts/**'
		}
	}
};

const clean = () => {
	console.log(config.build.dist);
	return del([config.build.dist, config.build.temp]);
};

const style = () => {
	return src(config.build.paths.styles, {
		base: config.build.src,
		cwd: config.build.src
	})
		.pipe(plugins.sass({outputStyle: 'expanded'}))
		.pipe(dest(config.build.temp))
		.pipe(bs.reload({stream: true}));
};
const script = () => {
	return src(config.build.paths.scripts, {
		base: config.build.src,
		cwd: config.build.src
	})
		.pipe(plugins.babel({presets: [require('@babel/preset-env')]}))
		.pipe(dest(config.build.temp))
		.pipe(bs.reload({stream: true}));
};

const page = () => {
	return src(config.build.paths.pages, {
		base: config.build.src,
		cwd: config.build.src
	})
		.pipe(plugins.swig({data: config.data, defaults: {cache: false}}))
		.pipe(dest(config.build.temp))
		.pipe(bs.reload({stream: true}));
};

const image = () => {
	return src(config.build.paths.images, {
		base: config.build.src,
		cwd: config.build.src
	})
		.pipe(plugins.imagemin())
		.pipe(dest(config.build.dist));
};

const font = () => {
	return src(config.build.paths.fonts, {
		base: config.build.src,
		cwd: config.build.src
	})
		.pipe(plugins.imagemin())
		.pipe(dest(config.build.dist));
};

const extra = () => {
	return src('**', {
		base: config.build.public,
		cwd: config.build.public
	}).pipe(dest(config.build.dist));
};

const useref = () => {
	return (
		src(config.build.paths.pages, {
			base: config.build.temp,
			cwd: config.build.temp
		})
			.pipe(plugins.useref({searchPath: [config.build.temp, '.', '../']}))
			// 创建了 HTML Js css 需要压缩 , 但是在执行之前需要重新执行打包，
			// 然后再去执行压缩，因为文件注释在压缩之后就消失了
			.pipe(plugins.if(/\.js$/, plugins.uglify()))
			.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
			.pipe(
				plugins.if(
					/\.html$/,
					plugins.htmlmin({
						collapseWhitespace: true,
						minifyCSS: true,
						minifyJS: true
					})
				)
			)
			.pipe(dest(config.build.dist))
	);
};
// 图片压缩，资源类压缩，一般在开发环境不做操作
const serve = () => {
	watch(config.build.paths.styles, {cwd: config.build.src}, style);
	watch(config.build.paths.scripts, {cwd: config.build.src}, script);
	watch(config.build.paths.pages, {cwd: config.build.src}, page);
	// watch('src/assets/images/**', image);
	// watch('src/assets/fonts/**', font);
	// watch('public/**', extra);
	watch([config.build.paths.images, config.build.paths.fonts], {cwd: config.build.src}, bs.reload);
	watch('**', {cwd: config.build.public}, bs.reload);
	bs.init({
		notify: false,
		port: 2080,
		open: false,
		// files: "dist/**",
		server: {
			baseDir: [config.build.temp, config.build.src, config.build.public],
			routes: {
				'/node_modules': './node_modules'
			}
		}
	});
};
const compile = parallel(style, script, page);
// 上线之前执行
const build = series(clean, parallel(series(compile, useref), image, font, extra));

const start = series(compile, serve);
module.exports = {
	build,
	start,
	clean,
	compile,
	useref
};
